#include "Extensions.h"

PFNGLGENBUFFERSARBPROC				glGenBuffers;
PFNGLDELETEBUFFERSARBPROC			glDeleteBuffers;
PFNGLBINDBUFFERARBPROC				glBindBuffer;
PFNGLBUFFERDATAARBPROC				glBufferData;
PFNGLBUFFERSUBDATAARBPROC			glBufferSubData;
PFNGLMAPBUFFERARBPROC				glMapBuffer;
PFNGLUNMAPBUFFERARBPROC				glUnmapBuffer;
PFNGLISBUFFERARBPROC				glIsBuffer;
PFNGLGETBUFFERSUBDATAARBPROC		glGetBufferSubData;
PFNGLGETBUFFERPOINTERVARBPROC		glGetBufferPointerv;
PFNGLGETBUFFERPARAMETERIVARBPROC	glGetBufferParameteriv;

PFNGLACTIVETEXTUREARBPROC			glActiveTexture;
PFNGLCLIENTACTIVETEXTUREARBPROC		glClientActiveTexture;
PFNGLMULTITEXCOORD1FARBPROC			glMultiTexCoord1f;
PFNGLMULTITEXCOORD1FVARBPROC		glMultiTexCoord1fv;
PFNGLMULTITEXCOORD2FARBPROC			glMultiTexCoord2f;
PFNGLMULTITEXCOORD2FVARBPROC		glMultiTexCoord2fv;

PFNGLGENVERTEXARRAYSPROC			glGenVertexArrays;
PFNGLDELETEVERTEXARRAYSPROC			glDeleteVertexArrays;
PFNGLISVERTEXARRAYPROC				glIsVertexArray;
PFNGLBINDVERTEXARRAYPROC			glBindVertexArray;

static bool isExtensionSupported(const char *ext, const char * extList)
{
    const char *start = extList;
    const char *ptr;

    while ((ptr = strstr ( start, ext)) != NULL)
    {
        const char *end = ptr + strlen(ext);

        if (isspace(*end) || *end == '\0')
            return true;

        start = end;
    }

    return false;
}

bool isExtensionSupported(const char *ext)
{
    initExtensions();

    const char *extensions = (const char *)glGetString(GL_EXTENSIONS);

    if (isExtensionSupported(ext, extensions))
	    return true;
	return false;
}

void initExtensions()
{
	static bool called = false;
	if (called)
		return;

	glGenBuffers				= (PFNGLGENBUFFERSARBPROC)wglGetProcAddress("glGenBuffersARB");
	glDeleteBuffers				= (PFNGLDELETEBUFFERSARBPROC)wglGetProcAddress("glDeleteBuffersARB");
	glBindBuffer				= (PFNGLBINDBUFFERARBPROC)wglGetProcAddress("glBindBufferARB");
	glBufferData				= (PFNGLBUFFERDATAARBPROC)wglGetProcAddress("glBufferDataARB");
	glBufferSubData				= (PFNGLBUFFERSUBDATAARBPROC)wglGetProcAddress("glBufferSubDataARB");
	glMapBuffer					= (PFNGLMAPBUFFERARBPROC)wglGetProcAddress("glMapBufferARB");
	glUnmapBuffer				= (PFNGLUNMAPBUFFERARBPROC)wglGetProcAddress("glUnmapBufferARB");
	glIsBuffer					= (PFNGLISBUFFERARBPROC)wglGetProcAddress("glIsBufferARB");
	glGetBufferSubData			= (PFNGLGETBUFFERSUBDATAARBPROC)wglGetProcAddress("glGetBufferSubDataARB");
	glGetBufferPointerv			= (PFNGLGETBUFFERPOINTERVARBPROC)wglGetProcAddress("glGetBufferPointervARB");
	glGetBufferParameteriv		= (PFNGLGETBUFFERPARAMETERIVARBPROC)wglGetProcAddress("glGetBufferParameterivARB");
	
	glActiveTexture				= (PFNGLACTIVETEXTUREARBPROC)wglGetProcAddress("glActiveTextureARB");
	glClientActiveTexture		= (PFNGLCLIENTACTIVETEXTUREARBPROC)wglGetProcAddress ( "glClientActiveTextureARB");
	glMultiTexCoord1f			= (PFNGLMULTITEXCOORD1FARBPROC)wglGetProcAddress("glMultiTexCoord1fARB");
	glMultiTexCoord1fv			= (PFNGLMULTITEXCOORD1FVARBPROC)wglGetProcAddress("glMultiTexCoord1fvARB");
	glMultiTexCoord2f			= (PFNGLMULTITEXCOORD2FARBPROC)wglGetProcAddress("glMultiTexCoord2fARB");
	glMultiTexCoord2fv			= (PFNGLMULTITEXCOORD2FVARBPROC)wglGetProcAddress("glMultiTexCoord2fvARB");

	glGenVertexArrays			= (PFNGLGENVERTEXARRAYSPROC)wglGetProcAddress("glGenVertexArrays");
	glDeleteVertexArrays		= (PFNGLDELETEVERTEXARRAYSPROC)wglGetProcAddress("glDeleteVertexArrays");
	glIsVertexArray				= (PFNGLISVERTEXARRAYPROC)wglGetProcAddress("glIsVertexArray");
	glBindVertexArray			= (PFNGLBINDVERTEXARRAYPROC)wglGetProcAddress("glBindVertexArray");

	called = true;
}